<!DOCTYPE html>
<html lang="zh-cn">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="../../assets/css/base.css">
</head>
<body>
    <div id="app">
        <!-- 
        组件数据共享和传递有哪些方式
            父向子：属性绑定加数据拦截;属性绑定加$attrs;
            子向父：
            非父子：
        -->
        <pre v-pre class="note">
        + 子组件标签在vue环境下是可以作为特殊标签调用vue部分指令的;指令的使用语法和普通标签的使用语法相同;
        + 因为组件的容器和实例是相互隔离的，所以父组件数据无法提供给子组件直接使用，因此需要解决父向子数据传递的问题；
            - 属性绑定+属性拦截
                => 属性绑定：使用vue指令 v-bind 在子组件自定义标签上绑定需要传递的属性;
                            子组件标签的调用等效于子组件创建的调用(功能类似mount函数);
                            子组件创建过程中，vue会将子组件标签上绑定的所有属性(动态属性、静态属性)进行加载读取，并在容器挂载后记录在当前组件实例中
                                                                            【子组件标签最终会被移除，只保留子组件容器内容】;
                            子组件标签上定义的属性被读取后存放于组件特殊属性【实例属性】 $attrs 中;
                => 属性拦截：vue提供一个**特殊的数据仓库props**，该仓库会在子组件中自动加载绑定在子组件标签上的属性；
                            props 会将被描述的属性，自动从 $attrs 中读取出来，并提供类似于 data 的数据仓库调用方式;
                            需要注意的是，被props拦截后的属性，会从$attrs中移除；
                            props 提供两种作用：简化传递属性数据的获取方式;提供子组件传递属性数据安全校验功能
        </pre>
        <h5>父组件</h5>
        <p>msg:{{ msg }}</p>
        <hr>
        <my-comp v-bind:msg="msg" :info="info" :list="arr" text="静态属性"></my-comp>
        <hr>

    </div>

    <script type="text/x-template" id="myComp">
        <div class="cbox" itany="网博">
            <h5>子组件</h5>
            <p>$attrs:{{ $attrs }}</p>
            <p>$attrs.msg:{{ $attrs.msg }}</p>
            <p>msg:{{ msg }}</p>
            <input type="button" value="printAttrAndSetMsg()" @click="printAttrAndSetMsg()">
            <p>info:{{ info }}</p>
            <p>list:{{ list }}</p>
            <p>text:{{ text }}</p>
        </div>
    </script>
    <script type="module">
        import { createApp } from "../../assets/vue3/vue.esm-browser.js";
        // 子组件实例
        const MyComp = {
            template:"#myComp",
            data() {
                return {
                    msg: ""
                }
            },
            props:["info","list","text"],
            methods: {
                printAttrAndSetMsg() {
                    console.log( this )
                    console.log( this.$attrs )
                    this.msg = this.$attrs.msg;
                }
            },
            beforeCreate () {
                console.log("MyComp组件被创建")
            },
            created () {
                this.msg = this.$attrs.msg;
            },
            mounted () {
                console.log("MyComp组件容器被挂载");
            },
        }

        // 父组件实例
        createApp({
            data() {
                return {
                    msg:"父组件msg",
                    info:"父组件info",
                    arr:[1,2,3,4,5]
                }
            },
            components: {
                MyComp,
            },
        }).mount("#app")
    </script>
</body>
</html>